# -*- coding: utf-8 -*-
import mechanize
from mechanize import Browser
import re
import cStringIO as StringIO
import lxml.html
from lxml import etree
from urllib import urlencode
import zlib
import datetime
import sys
import cherrypy
import logging
from mongolog.handlers import MongoHandler
try: 
    import json
except ImportError: 
    import simplejson as json

# <!--- basic function --
def getCRC32Unsign(textToHash=None):
    return str(zlib.crc32(textToHash) & 0xffffffffL)

def buildTree(url, ishtml=False, isAjax=False):
    ua6300 = "Nokia6300/2.0 (04.20) Profile/MIDP-2.0 Configuration/CLDC-1.1 UNTRUSTED/1.0"
    br = Browser()
    br.set_handle_equiv(True)
    br.set_handle_redirect(True)
    br.set_handle_referer(True)
    br.set_handle_robots(False)
    br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)
    if not isAjax:  br.addheaders = [("User-Agent", ua6300)]
    else:   br.addheaders = [("User-Agent", ua6300), ("X-Requested-With", "XMLHttpRequest")]
    br.open(url, None, 600)
    html = br.response().read()
    if ishtml: print html
    parser = etree.HTMLParser(encoding='utf-8')
    tree = etree.parse(StringIO.StringIO(html), parser)
    return tree

def getElementText(elem):
    if elem is None: return ''
    t = lxml.html.fromstring(etree.tostring(elem))
    return t.text_content().strip()

def getAttributeText(node, attrb):
    if node is None or attrb == '': return ''
    return node.get(attrb)

def extractWithRegEx(pat, matchStr, matchIdx):
    ''' Hàm chạy regex và trả kết quả ở group[matchIdx]. Nếu không có kết quả -> trả về null'''
    try:
        result = ''
        rexp = re.compile(pat)
        m = rexp.search(matchStr)
        if (m!=''):
            result = m.group(matchIdx)
        return result
    except:
        return ''

def strToASCII(str):
    if str == '': return ''
    try:
        listPattern = [r"á|à|ả|ạ|ã|â|ấ|ầ|ẩ|ậ|ẫ|ă|ắ|ằ|ẳ|ặ|ẵ", r"Á|À|Ả|Ạ|Ã|Â|Ấ|Ầ|Ẩ|Ậ|Ẫ|Ă|Ắ|Ằ|Ẳ|Ặ|Ẵ",
                       r"đ", r"Đ", r"í|ì|ỉ|ị|ĩ", r"Í|Ì|Ỉ|Ị|Ĩ", r"é|è|ẻ|ẹ|ẽ|ê|ế|ề|ể|ệ|ễ", r"É|È|Ẻ|Ẹ|Ẽ|Ê|Ế|Ề|Ể|Ệ|Ễ",
                       r"ó|ò|ỏ|ọ|õ|ô|ố|ồ|ổ|ộ|ỗ|ơ|ớ|ờ|ở|ợ|ỡ", r"Ó|Ò|Ỏ|Ọ|Õ|Ô|Ố|Ồ|Ổ|Ộ|Ỗ|Ơ|Ớ|Ờ|Ở|Ợ|Ỡ",
                       r"ú|ù|ủ|ụ|ũ|ư|ứ|ừ|ử|ự|ữ", r"Ú|Ù|Ủ|Ụ|Ũ|Ư|Ứ|Ừ|Ử|Ự|Ữ", r"ý|ỳ|ỷ|ỵ|ỹ", r"Ý|Ỳ|Ỷ|Ỵ|Ỹ"]
        rep = ['a', 'A', 'd', 'D', 'i', 'I', 'e', 'E', 'o', 'O', 'u', 'U', 'y', 'Y']
        str = str.encode('utf-8', 'replace')
        for idx in range(len(listPattern)):
            str = re.sub(listPattern[idx], rep[idx], str)
        return str
    except:
        pass

# -- end basic function --!>

def compareURL(curURL, nextURL):
    curStart = extractWithRegEx("start=(\d+)", curURL, 1)
    nextStart = extractWithRegEx("start=(\d+)", nextURL, 1)
    print "\n\tcurstart {0} -- nextstart {1}".format(curStart, nextStart)
    if curStart == nextStart:   return True
    return False


class GoogleFlickr():
    
    @cherrypy.expose
    def index(self):
        return "Google images and flickr"
    
    @cherrypy.expose
    def google(self, q, pg):
        if pg == '' or int(pg) < 1: pg = 1
        startRow = (int(pg) - 1) * 14
        url = "http://images.google.com/m?site=images&{0}&start={1}&sa=N".format(urlencode({'q': q}), startRow)
        print url
        try:
            results = []
            tree = buildTree(url)
            if len(tree.xpath("//div[@id='navbar']/following-sibling::*[1]/div//img[@class]")) < 1: return json.dumps({})
            for item in tree.xpath("//div[@id='navbar']/following-sibling::*[1]/div//img[@class]"):
                gLink = getAttributeText(item, 'src')
                rLink = "http://{0}".format(extractWithRegEx(r"::(.+\.(jpg|jpe|jpeg|png|gif|bmp|JPG|JPE|JPEG|PNG|GIF|BMP))", gLink, 1))
                results.append({'thumbnail': gLink, 'detailImage': rLink})
            return json.dumps(results)
        except:
            errMsg = "{0} - {1} >> {2}".format(q, pg, sys.exc_info()[0])
            log.error(errMsg)
            print errMsg
            sys.exit()
    
    @cherrypy.expose
    def fdetail(self, url):
        try:
            tree = buildTree(url, False, True)
            return json.dumps({'detailImage': tree.xpath("//img[@class='photo_img']/@src")[0]})
        except:
            errMsg = "{0} >> {1}".format(sys.exc_info()[0], url)
            log.error(errMsg)
            print errMsg
            sys.exit()
    
    @cherrypy.expose
    def flickr(self, q, pg):
        try:
            data = urlencode({'q': q})
            if pg == '' or int(pg) < 1: pg = 1
            url = "http://m.flickr.com/search/advanced/?{0}&page={1}".format(data, pg)
            print url
            tree = buildTree(url, False, True)
            if len(tree.xpath("//span[@class='subtitle not-found not-found-subtitle']")) > 0:
                print "not found"
                return json.dumps({})
            results = []
            for item in tree.xpath("//ul[@class='photo-list hide-sub-nav']/li[position()<last() and position()>1]"):
                thmbNode = item.xpath(".//img[@class='pc_img']")
                if len(thmbNode) > 0:   thumbnail = getAttributeText(thmbNode[0], 'src')
                detailLink = mechanize.urljoin(url, getAttributeText(item.xpath("./a[contains(@href, 'in/search?q')]")[0], 'href'))
                title = getElementText(item.xpath(".//div[@class='meta_block']/p[1]")[0])
                fromAlbum = getElementText(item.xpath(".//div[@class='meta_block']/p[@class='from']")[0])
                results.append({'title': title, 'thumbnail': thumbnail, 'fromAlbum': fromAlbum, 'detailLink': detailLink})
                
            return json.dumps(results)
        except:
            errMsg = "{0} >> {1}".format(sys.exc_info()[0], url)
            log.error(errMsg)
            print errMsg
            sys.exit()
        
    
if __name__ == '__main__':
    
    log = logging.getLogger('GoogleFlickr')
    log.setLevel(logging.DEBUG)
    log.addHandler(MongoHandler.to('mongolog', 'log'))
    global_conf = {
        'global': {
        'server.socket_host': '127.0.0.1',
        'server.socket_port': 8889,
        'tools.encode.on': True,
        'tools.encode.encoding': 'UTF-8'
        },
    }
    cherrypy.config.update(global_conf)
    cherrypy.quickstart(GoogleFlickr())
    print ">> Finished at {0}".format(str(datetime.datetime.now()))
    sys.exit()